package ch.rheintalconnection.sysventory.presentation.panels;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import ch.rheintalconnection.sysventory.application.PCAttribute;
import ch.rheintalconnection.sysventory.application.PCDatas;
import ch.rheintalconnection.sysventory.application.SearchCommand;
import ch.rheintalconnection.sysventory.businessServices.DataService;
import ch.rheintalconnection.sysventory.domain.Client;
import ch.rheintalconnection.sysventory.domain.User;
import ch.rheintalconnection.sysventory.technicalServices.IDataReader;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Select;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class SearchPanel extends VerticalLayout {

	private static final long serialVersionUID = -7380199582043334218L;

	private static Logger logger = LogManager.getLogger(SearchPanel.class);
	
	private TextField searchComputername;
	private TextField searchIpAddress;
	private TextField searchCompterType;
	private TextField searchProcessorFamily;
	private TextField searchOsType;

	private Select selectOthers;
	private Select selectOS;
	private Select selectProcessor;
	private Select selectComputer;
	private Select selectNIC;
	private Label lblSelectInfo;
	
	private Button btnSearch;
	
	private ValueChangeListener valueChangeListener;
	private ButtonClickListener buttonClickListener;
	
	private SearchCommand searchCommand;
	
	private List<PCAttribute> displayAttributes;
	//private List<SearchString> searchStrings;
	private HashMap<PCAttribute, String> searchStrings;
	
	private TablePanel tablePanel;
	@SuppressWarnings("unused")
	private User user;
	private IDataReader dataReader;
	private VerticalLayout historyPanelContainer;
		
	@SuppressWarnings("deprecation")
	SearchPanel(DataService dataService, IDataReader dataReader) {


		this.dataReader = dataReader;
		
		searchCommand = new SearchCommand(dataService);
		displayAttributes = new ArrayList<PCAttribute>();
		searchStrings = new HashMap<PCAttribute, String>();			
		
		// Listeners
		valueChangeListener = new ValueChangeListener();
		buttonClickListener = new ButtonClickListener();
		
		
		// SearchLayout
		HorizontalLayout searchLayout = new HorizontalLayout();
		this.addComponent(searchLayout);

		searchComputername = new TextField(PCAttribute.PCName.getPresentationName());
		searchIpAddress = new TextField(PCAttribute.NICIP.getPresentationName());
		searchCompterType = new TextField(PCAttribute.PCType.getPresentationName());
		searchProcessorFamily = new TextField(PCAttribute.CPUFamily.getPresentationName());
		searchOsType = new TextField(PCAttribute.OSName.getPresentationName());
		
		searchLayout.addComponent(searchComputername);
		searchLayout.addComponent(searchIpAddress);
		searchLayout.addComponent(searchCompterType);
		searchLayout.addComponent(searchProcessorFamily);
		searchLayout.addComponent(searchOsType);
		
		searchComputername.setValue("*");
		searchIpAddress.setValue("*");
		searchCompterType.setValue("*");
		searchProcessorFamily.setValue("*");
		searchOsType.setValue("*");

		// AttributeSelectionLayout
		HorizontalLayout attributeSelectionLayout = new HorizontalLayout();
		this.addComponent(attributeSelectionLayout);

		selectOthers = new Select("Andere");
		selectOS = new Select("Betriebsystem");
		selectProcessor = new Select("Prozessor");
		selectComputer = new Select("Computer");
		selectNIC = new Select("NIC");
		lblSelectInfo = new Label();
		
		selectOthers.setImmediate(true);
		selectOS.setImmediate(true);
		selectProcessor.setImmediate(true);
		selectComputer.setImmediate(true);
		selectNIC.setImmediate(true);
		
		selectOthers.addListener(valueChangeListener);
		selectOS.addListener(valueChangeListener);
		selectProcessor.addListener(valueChangeListener);
		selectComputer.addListener(valueChangeListener);
		selectNIC.addListener(valueChangeListener);
		
		
		selectOthers.setMultiSelect(true);
		selectOS.setMultiSelect(true);
		selectProcessor.setMultiSelect(true);
		selectComputer.setMultiSelect(true);
		selectNIC.setMultiSelect(true);

		attributeSelectionLayout.addComponent(selectOthers);
		attributeSelectionLayout.addComponent(selectOS);
		attributeSelectionLayout.addComponent(selectProcessor);
		attributeSelectionLayout.addComponent(selectComputer);
		attributeSelectionLayout.addComponent(selectNIC);
		attributeSelectionLayout.addComponent(lblSelectInfo);
		// Items for SelectionLists

		List<PCAttribute> lOthers = new ArrayList<PCAttribute>();
		List<PCAttribute> lOS = new ArrayList<PCAttribute>();
		List<PCAttribute> lProcessor = new ArrayList<PCAttribute>();
		List<PCAttribute> lComputer = new ArrayList<PCAttribute>();
		List<PCAttribute> lNic = new ArrayList<PCAttribute>();

		lOthers.add(PCAttribute.ScanDate);
		lOthers.add(PCAttribute.Programs);
		lOthers.add(PCAttribute.Printers);

		lOS.add(PCAttribute.OSName);
		lOS.add(PCAttribute.OSVersion);
		lOS.add(PCAttribute.OSTechnology);
		
		lProcessor.add(PCAttribute.CPUDesc);
		lProcessor.add(PCAttribute.CPUFamily);
		lProcessor.add(PCAttribute.CPUCores);
		lProcessor.add(PCAttribute.CPUClockrate);

		lComputer.add(PCAttribute.PCName);
		lComputer.add(PCAttribute.PCRAM);
		lComputer.add(PCAttribute.PCRAM);
		lComputer.add(PCAttribute.PCHD);

		lNic.add(PCAttribute.NICIP);
		lNic.add(PCAttribute.NICMacAddress);
		lNic.add(PCAttribute.NICDesc);
		lNic.add(PCAttribute.NICGateway);
		lNic.add(PCAttribute.NICDHCP);
		lNic.add(PCAttribute.NICSubnet);
		
		configureListSelect(selectOthers, lOthers);
		configureListSelect(selectOS, lOS);
		configureListSelect(selectProcessor, lProcessor);
		configureListSelect(selectComputer, lComputer);
		configureListSelect(selectNIC, lNic);

		// Suchenbutten
		btnSearch = new Button("Suchen");
		this.addComponent(btnSearch);
		btnSearch.addListener(buttonClickListener);
		
		// Tabelle initialisieren
		tablePanel = new TablePanel("TITEL", dataReader, true);
		tablePanel.setHistoryClickListener(new HistoryButtonHandler());
		this.addComponent(tablePanel);
		
		// HistoryPanelContainer erzeugen
		historyPanelContainer = new VerticalLayout();
		this.addComponent(historyPanelContainer); 

	}

	private void configureListSelect(Select select, List<PCAttribute> lItems) {

		select.removeAllItems();

		for (PCAttribute element : lItems) {
			select.addItem(element);
		}

		select.setNullSelectionAllowed(true);
	}

	
	
	private class ValueChangeListener implements Property.ValueChangeListener{

		private static final long serialVersionUID = -6199848204799057806L;

		@SuppressWarnings("unchecked")
		public void valueChange(ValueChangeEvent event) {
			logger.info("ValueChanged event wurde ausgelöst.");
       
			Set<PCAttribute> othersSet = (Set<PCAttribute>) selectOthers.getValue();
			Set<PCAttribute> osSet = (Set<PCAttribute>) selectOS.getValue();
			Set<PCAttribute> processorSet = (Set<PCAttribute>) selectProcessor.getValue();
			Set<PCAttribute> computersSet = (Set<PCAttribute>) selectComputer.getValue();
			Set<PCAttribute> nicSet = (Set<PCAttribute>) selectNIC.getValue();
	        
			displayAttributes.clear();
			
			if(othersSet != null){
				displayAttributes.addAll(othersSet);
			}
			if(osSet != null){
				displayAttributes.addAll(osSet);
			}
			if(processorSet != null){
				displayAttributes.addAll(processorSet);
			}
			if(computersSet != null){
				displayAttributes.addAll(computersSet);
			}
				
			if(nicSet != null){
				displayAttributes.addAll(nicSet);
			}
			
			if(displayAttributes.size() > 8)
			{
				lblSelectInfo.setValue("Es dürfen maximal acht Attribute ausgewählt werden.");
			}else {
				lblSelectInfo.setValue("");
			}
			
	        
		}
		
	}
	
	private class ButtonClickListener implements Button.ClickListener{

		private static final long serialVersionUID = -2236038444248921397L;

		public void buttonClick(ClickEvent event) {
			logger.info("Suchen-Button wurde gedrückt.");
			
	
			searchStrings.clear();
			searchStrings.put(PCAttribute.PCName, (String) searchComputername.getValue());
			searchStrings.put(PCAttribute.NICIP, (String) searchIpAddress.getValue());
			searchStrings.put(PCAttribute.PCType, (String) searchCompterType.getValue());
			searchStrings.put(PCAttribute.CPUFamily, (String) searchProcessorFamily.getValue());
			searchStrings.put(PCAttribute.OSName, (String) searchOsType.getValue());
			
			
			if(searchCommand.validateSearchStrings(searchStrings)){
				List<PCDatas> pcdatasList = searchCommand.search(searchStrings);
				tablePanel.initializeTable();
				tablePanel.fillTable(displayAttributes, pcdatasList);
				historyPanelContainer.removeAllComponents();
			}
		}
	}
	
	
	private class HistoryButtonHandler implements Button.ClickListener{

		private static final long serialVersionUID = 2414416133530141966L;

		@Override
		public void buttonClick(ClickEvent event) {
			
			Button but = event.getButton();
			Client client = (Client) but.getData();
			HistoryPanel historyPanel = new HistoryPanel(client, dataReader);
			historyPanelContainer.removeAllComponents();
			historyPanelContainer.addComponent(historyPanel);
		}
	}
	

	public void setUser(User user) {
		this.user = user;
	}
	

}
